class Vue {
    constructor(options){
        // 初始化内部的属性
        this.$options = options || {}
        this.$data = this.$options.data || {}
        this.$el = typeof this.$options.el  === 'string' ? document.querySelector(this.$options.el) : this.$options.data.el
        this._proxyData(this.$data);
        this._initMethods(options.methods);
        // 设置数据监听 ,为 data 属性加上 getter 和  setter
        new Obsever(this.$data);
        new Compiler(this)
    }
    /**
     * 将数据进行 getter 和 setter
     * 1. 将data上的属性绑定到 Vue 实例上
     * 2. 为这些属性设置 getter 和 setter 
     * 
     * @param {*} data 
     */
    _proxyData(data) {
       Object.keys(data).forEach(key => {
           Object.defineProperty(this, key, {
               enumerable: true,
               configurable: true,
               get () {
                   return data[key];
               },
               set (newVal) {
                   if(data[key]  === newVal) return;
                    data[key] = newVal;
               }
           })
       })
    }
    // 初始化 methods
    _initMethods(methods) {
      if(typeof methods === 'object'){
          for (const key in methods) {
              if(key in this){
                  console.warn(key + ' property is already defined!');
                  continue;
              }
              if(typeof methods[key] !== 'function'){
                console.warn(key + ' property is not function!');
                continue;
              }
              this[key] = methods[key];
          }
      }
    }
}